#pragma once

template<int size,typename type = number>
struct Vector {
 type pos[size];
 type & x(void) {
  return pos[0];
 }
 type & y(void) {
  return pos[1];
 }
 type & z(void) {
  return pos[2];
 }
 type & w(void) {
  return pos[3];
 }
 type & operator[](int i) {
  return pos[i];
 }
 type & operator[](char i) {
  switch (i) {
   case 'x':
    return pos[0];
   case 'y':
    return pos[1];
   case 'z':
    return pos[2];
  }
 }
 template<typename t> // for lambda functions
 void forEach(t cake) {
  FORALL(size) {
   cake(pos[i]);
  }
 }
 Vector<size,type> & operator+(Vector<size,type> other) {
  FORALL(size) {
   pos[i] + other.pos[i];
  }
  return *this;
 }
 Vector<size,type> & operator-(Vector<size,type> other) {
  FORALL(size) {
   pos[i] - other.pos[i];
  }
  return *this;
 }
 Vector<size,type> & operator*(Vector<size,type> other) {
  FORALL(size) {
   pos[i] * other.pos[i];
  }
  return *this;
 }
 Vector<size,type> & operator/(Vector<size,type> other) {
  FORALL(size) {
   pos[i] / other.pos[i];
  }
  return *this;
 }
 Vector<size,type> & operator+=(Vector<size,type> other) {
  FORALL(size) {
   pos[i] += other.pos[i];
  }
  return *this;
 }
 Vector<size,type> & operator-=(Vector<size,type> other) {
  FORALL(size) {
   pos[i] -= other.pos[i];
  }
  return *this;
 }
 Vector<size,type> & operator*=(Vector<size,type> other) {
  FORALL(size) {
   pos[i] *= other.pos[i];
  }
  return *this;
 }
 Vector<size,type> & operator/=(Vector<size,type> other) {
  FORALL(size) {
   pos[i] /= other.pos[i];
  }
  return *this;
 }
 Vector<size,type> & operator+(number other) {
  FORALL(size) {
   pos[i] + other;
  }
  return *this;
 }
 Vector<size,type> & operator-(number other) {
  FORALL(size) {
   pos[i] - other;
  }
  return *this;
 }
 Vector<size,type> & operator*(number other) {
  FORALL(size) {
   pos[i] * other;
  }
  return *this;
 }
 Vector<size,type> & operator/(number other) {
  FORALL(size) {
   pos[i] / other;
  }
  return *this;
 }
 Vector<size,type> & operator+=(number other) {
  FORALL(size) {
   pos[i] += other;
  }
  return *this;
 }
 Vector<size,type> & operator-=(number other) {
  FORALL(size) {
   pos[i] -= other;
  }
  return *this;
 }
 Vector<size,type> & operator*=(number other) {
  FORALL(size) {
   pos[i] *= other;
  }
  return *this;
 }
 Vector<size,type> & operator/=(number other) {
  FORALL(size) {
   pos[i] /= other;
  }
  return *this;
 }
};
